#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>

using std::cout;
using std::endl;
using std::string;

// // 自定义捕捉信号
// void catchSig(int signum)
// {
//     cout << "该进程捕捉到一个信号: " << signum << " pid" << getpid() << endl;
// }

// int main()
// {
//     signal(SIGINT, catchSig);  // ctrl + c   2号 -> t退出信号

//     signal(SIGQUIT, catchSig);  // ctrl + \  3号 -> 终止信号

//     while (true)
//     {
//         cout << "我是一个进程,我正在运行, PID: " << getpid() << endl;
//         sleep(1);
//     }
//     return 0;
// }

// int main()
// {
//     pid_t id = fork();
//     if (id == 0)
//     {
//         // 子进程
//         cout << getpid() << endl;
//         while (1) {}
//     }
//     int status = 0;
//     waitpid(-1, &status, 0);  // 阻塞式等待
//     cout << "父进程: " << getpid() << " 子进程: " << id << " exit sig: " << (status & 0x7F)
//     << " is core: " << ((status >> 7) & 1) << endl;

//     return 0;
// }

// void catchSig(int signum)
// {
//     sleep(1);
//     cout << "获取了以一个信号: " << signum << endl;
//     exit(1);
// }
// int main()
// {
//     signal(SIGINT, catchSig);

//     while (true)
//     {
//         cout << "我是一个进程,我正在运行..., pid: " << getpid() << endl;
//         sleep(1);

//         int a = 100;
//         a /= 0;

//         cout << "run here ..." << endl;
//     }

//     pid_t id = fork();

//     if (id == 0)
//     {
//         sleep(1);
//         int a = 100;
//         a /= 0;
//         exit(1);
//     }

//     int status = 0;
//     waitpid(id, &status, 0);
//     cout << "父进程: " << getpid() << " 子进程: " << id << " exit Sig: " << (status & 0x7F)
//      << " is core: " << ((status >> 7) & 1) << endl;
//     return 0;
// }

// // 实现 kill 功能
// void Usage(string proc)
// {
//     cout << "Usage: \r\n\t" << proc << " signumber processid" << endl;
// }

// int main(int argc, char* argv[])
// {
//     if (argc != 3)
//     {
//         Usage(argv[0]);
//         exit(0);
//     }

//     int signumber = atoi(argv[1]);
//     int procid = atoi(argv[2]);

//     kill(procid, signumber);
//     return 0;
// }

// // 给自己发送信号？ raise()  -> 自己发送信号
// int main()
// {
//     cout << "我是一个进程,我正在运行 ... " << endl;
//     sleep(3);
//     // raise(9);
//     abort();  // -> 发生核心转储
//     return 0;
// }

// // 软件产生信号  ->  父子进程通过管道读写, 一端关闭, OS给另一个发送SIGPIPE信号 -> 13号
// int main()
// {
//     pid_t id = fork();
//     if (id < 0)
//     {
//         perror("fork error");
//         exit(0);
//     }
//     int pipefd[2] = {0};
//     int n = pipe(pipefd);
//     if (n == -1)
//     {
//         perror("pipe error");
//         exit(1);
//     }

//     if (id == 0)
//     {
//         // 子进程
//         close(pipefd[0]); // 关闭读端

//         std::string message = "我是子进程,我正在给你发送消息!";
//         int count = 0;
//         char send_buffer[1024];
//         while (true)
//         {
//             snprintf(send_buffer, sizeof(send_buffer), "%d: %s", count++, message.c_str()); // 构建一个变化的字符串

//             write(pipefd[1], send_buffer, strlen(send_buffer));

//             sleep(1);
//         }
//     }

//     // 父进程
//     close(pipefd[1]); // 关闭写端,子进程进行读

//     char buffer[1024];
//     int time = 0;
//     while (true)
//     {
//         ssize_t s = read(pipefd[0], buffer, sizeof(buffer) - 1);
//         if (s > 0)
//         {
//             buffer[s] = 0;
//             cout << "child get a message[" << getpid() << "] " << "Father# " << buffer << endl;
//         }
//         else if (s == 0)
//         {
//             cout << "write quit(father), me quit" << endl;
//             break;
//         }
//         time++;
//         if (time == 5) break;
//         sleep(1);
//     }

//     close(pipefd[0]);

//     int status = 0;
//     waitpid(-1, &status, 0);
//     cout << "子进程退出信号: " << (status & 0x7F) << " 退出码: " << ((status >> 8) & 0xFF) << endl;
//     return 0;
// }

#include <functional>
#include <vector>
using std::vector;
using std::function;
// 使用闹钟信号来设置简单的计数器
uint64_t count = 0;
typedef function<void ()> func;
vector<func> callbacks;

void showCount()
{
    cout << "final count: " << count << endl;
}

void showLog()
{
    cout << "这个是日志功能" << endl;
}

void logUser()
{
    if (fork() == 0)
    {
        execl("/usr/bin/who", "who", nullptr);
        exit(1);
    }
}

void catchSig(int signum)
{
    cout << "获得一个信号: " << signum << " count: " << count << endl;
    for (auto& f : callbacks)
    {
        f();
    }
    alarm(1);
}

// int main()
// {
//     // // 验证1秒之内,会进行多少次count++
//     // alarm(1);  // 设置一个闹钟,一旦触发,这个闹钟就移除了
//     // int count = 0;
//     // while (true)
//     // {
//     //     cout << "count: " << count++ << endl;   // 这里主要是IO效率太慢了
//     // }

//     // 单纯的计算 算力
//     signal(SIGALRM, catchSig);
//     alarm(1);

//     callbacks.push_back(showCount);
//     callbacks.push_back(showLog);
//     callbacks.push_back(logUser);
//     while (true) count++;
// }


// 硬件产生信号
void handler(int signum)
{
    sleep(1);
    cout << "获得了一个信号: " << signum << endl;
    exit(0);
}
int main(int argc, char* argv[])
{
    // // 1.野指针问题 -> MMU硬件报错
    // signal(SIGSEGV, handler);
    // int* p = nullptr;
    // *p = 100;

    // 2.除0错误 -> CPU报错
    signal(SIGFPE, handler);
    int a = 100;
    a /= 0;
    return 0;
}
